package com.g2.rpc.util;

import com.g2.rpc.rpc.Invoker;
import com.g2.rpc.rpc.RpcInvocation;

import java.lang.reflect.Proxy;

/**
 * 描述:
 * ${DESCRIPTION}
 *
 * @author lingjiu.kong
 * @version 1.0
 * @date 2021-03-05 22:42
 */
public class ProxyFactory {

    public static Object getProxy(Class<?> clazz, Invoker invoker) {
        return Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, (proxy, method, args) -> {
            if (method.getDeclaringClass() == Object.class) {
                return method.invoke(invoker, args);
            }
            String methodName = method.getName();
            Class<?>[] parameterTypes = method.getParameterTypes();
            // 不需要远程调用
            if (parameterTypes.length == 0) {
                if ("toString".equals(methodName)) {
                    return invoker.toString();
                } else if ("$destroy".equals(methodName)) {
                    return null;
                } else if ("hashCode".equals(methodName)) {
                    return invoker.hashCode();
                }
            } else if (parameterTypes.length == 1 && "equals".equals(methodName)) {
                return invoker.equals(args[0]);
            }
            // method, invoker.getInterface().getName(), args;
            RpcInvocation rpcInvocation = new RpcInvocation();
            rpcInvocation.setMethodName(methodName);
            rpcInvocation.setArguments(args);
            rpcInvocation.setParameterTypes(parameterTypes);
            rpcInvocation.setServiceName(method.getDeclaringClass().getName());
            return invoker.invoke(rpcInvocation);
        });
    }

}
